package org.jeecg.modules.cascv.image.service.merge.liangxianggui;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.RandomUtil;
import com.NativeImageIO;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.config.TaskExecutePool;
import org.jeecg.modules.cascv.image.service.merge.ImageService;
import org.jeecg.modules.cascv.image.util.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @author贺弘烨
 * @Version 2022/3/21
 * description;
 */
@Slf4j
@Service
public class LiangxiangguiApp1Service extends ImageService {

    @Value("${imageurl}")
    private String imageurl;

    @Autowired
    private TaskExecutePool taskExecutePool;

    //    public static String frames_field = "A1_TPSR_MICU_APP1DATA_32_2021_1";
//    public static String imageNum_field = "A1_TPSR_MICU_APP1DATA_22_25_1";
//    public static String width_field = "A1_TPSR_MICU_APP1DATA_26_27_1";
//    public static String height_field = "A1_TPSR_MICU_APP1DATA_28_29_1";

    public long start = 0;
    public int i = 0;
    @Override
    public String idsNames() {
        return "TGMTYY1401_09CH_31_TPSRAPP1,TGMTYY1401_09CH_31_TPSRAPP2,TGMTYY1401_09CH_31_TPSRAPP5,TGMTYY1401_09CH_31_TPSRAPP6,TGMTYY1401_09CH_31_TPSRAPPUDP1,6D1DH_40H,6D1EH_40H,6D21H_40H,6D22H_40H,6D1DH_40H_UDP,6D1EH_40H_UDP,6D21H_40H_UDP,6D22H_40H_UDP,";
    }

    @Override
    public Result<Object> merge(JSONObject jsonObject, String idsName, String key) {
        long starttime = System.currentTimeMillis();

        if(i==0){
            start= System.currentTimeMillis();
            i=1;
        }
        if (idsName.contains("UDP")) {
            String firstFrame = "";
            //String secondFrame = "";
            //获取帧数据
            String frame = jsonObject.getString(idsName);
          //  System.out.println("frame = " + frame);
            //如果数据小于420*2 和null 直接跳到下一个数据
            if (null==frame||frame.length()<500) {
                return null;
            }
            //判断长度是否为1640
            if (frame.length() > 1000) {
                firstFrame = LaptopConstant.UDPData.get(key);
                //判断是否存在第一帧820
                if (firstFrame == null) {
                    LaptopConstant.UDPData.put(key, frame);
                    //如果存在第一帧那么继续添加到第二帧820
                } else if (firstFrame.length()>1000&&firstFrame.length()<=840*2){
                    firstFrame = LaptopConstant.UDPData.get(key);
                    firstFrame+=frame;
                    LaptopConstant.UDPData.put(key, firstFrame);
                }else {
                    LaptopConstant.UDPData.remove(key);//清除前面存入的帧数据
                }

            } else if (frame.length() < 1000) { //判断是否为第三针
                firstFrame = LaptopConstant.UDPData.get(key); //获取第一帧和第二帧的数据
                //System.out.println("firstFrame = " + firstFrame);
                if (null!=firstFrame&&firstFrame.length()>=3000) { //如果第一帧和第二帧都正确 就合并三帧 然后计算出数据，去合成图片
                    LaptopConstant.UDPData.remove(key);//清除前面存入的帧数据
                    frame = firstFrame+frame;
                    JSONObject parse = parse(frame, idsName);
                    if(parse==null){
                        return null;
                    }
                    String secondStr = parse.getString("second");
                     secondStr = secondStr.split(";")[1];
                    // long second = Long.parseLong(secondStr);
                    String subsecond = parse.getString("subsecond");
                   // secondStr = LaptopUtil.toDayHoursMinSec(second);
                    String dataFrames = parse.getString(LaptopConstant.FRAME_FIELD_MAP.get(idsName));
                    String nextImageNum = parse.getString(LaptopConstant.IMAGENUM_FIELD_MAP.get(idsName));
                    nextImageNum = nextImageNum.split(";")[1];//获取图像编号
                    dataFrames = dataFrames.split(";")[1];
                    dataFrames = dataFrames.substring(2).trim(); //获取需要解析的图像数据
                    StringBuilder queue = LaptopConstant.imageData.get(key);
                    composite(idsName, key, parse, dataFrames, queue, nextImageNum, secondStr, subsecond,start);
                }
            }
        } else {
            JSONObject conJson = jsonObject.getJSONObject("Content");

            //打印报错不连续的包序号
            String packageNum = conJson.getString(LaptopConstant.Package_number_MAP.get(idsName));
            int intpackageNum = Integer.parseInt(packageNum.split(";")[1]);
            Integer lastPackageNum = LaptopConstant.packageNumMap.get(key);

            if(null==lastPackageNum){
                LaptopConstant.packageNumMap.put(key,intpackageNum);
            }else {
                LaptopConstant.packageNumMap.put(key,intpackageNum);
                if (lastPackageNum + 1 != intpackageNum) {
                    if (16383 != lastPackageNum && 0 != intpackageNum) {
                        log.error("图像丢包，包序号不连续，当前包的包序号:"+intpackageNum+"，上一包包序号:"+lastPackageNum);
                    }
                }
            }

            String secondStr = jsonObject.getString("second");
            long second = Long.parseLong(secondStr);
            String subsecond = jsonObject.getString("subsecond");
            secondStr = LaptopUtil.toDayHoursMinSec(second);

            String nextImageNum = conJson.getString(LaptopConstant.IMAGENUM_FIELD_MAP.get(idsName));
            String dataFrames = conJson.getString(LaptopConstant.FRAME_FIELD_MAP.get(idsName));
            nextImageNum = nextImageNum.split(";")[0];//获取图像编号
          dataFrames = dataFrames.split(";")[1];
        //    dataFrames = dataFrames.substring(7, dataFrames.length() - 10);
           dataFrames = dataFrames.substring(2).trim(); //获取需要解析的图像数据
            StringBuilder queue = LaptopConstant.imageData.get(key);
            composite(idsName, key, conJson, dataFrames, queue, nextImageNum, secondStr, subsecond,start);
        }

        return null;
    }

    public boolean composite(String idsName, String key, JSONObject content, String dataFrames, StringBuilder queue, String currImageNum, String secondStr, String subSecondStr,long starttime) {

        //获取上一个图像编号
        String lastImageNum = LaptopConstant.imageNumMap.get(key);
   //     System.out.println("lastImageNum = " + lastImageNum);
   //     System.out.println("currImageNum = " + currImageNum);

        //获取宽度
        int width = Integer.parseInt((content.getString(LaptopConstant.WIDTH_FIELD_MAP.get(idsName))).split(";")[0]);
        //获取高度
        int height = Integer.parseInt((content.getString(LaptopConstant.HEIGHT_FIELD_MAP.get(idsName))).split(";")[0]);

        //  System.out.println("imageNum=" + lastImageNum);
        //  System.out.println("nextImageNum=" + currImageNum);

        //判断图像编号是否相同，不相同生成图片 相同继续拼接数据
        if (lastImageNum == null || lastImageNum.equals(currImageNum)) {
            if (queue != null) {
                queue.append(dataFrames);
                LaptopConstant.imageData.put(key, queue);
            } else {
                queue = new StringBuilder();
                LaptopConstant.imageData.put(key, queue);
                queue.append(dataFrames);
            }
        } else {
            //将数据 转16进制的byte型数组
           // String imgHexStr = LaptopConstant.imageData.get(key).toString();
            StringBuilder stringBuilder = LaptopConstant.imageData.get(key);

            while (stringBuilder.length() < 2592 * 1944 * 2) {
                stringBuilder.append("0");
            }
            while (stringBuilder.length() > 2592 * 1944 * 2) {
                stringBuilder.delete(stringBuilder.length() - 1, stringBuilder.length());
            }
            //将数据 转16进制的byte型数组
            String imgHexStr = stringBuilder.toString();


            if (imgHexStr.length()/2 >= width * height) {
                if (i==1){
                    log.info("接收到第一帧到能合成一张图片时间:"+(System.currentTimeMillis()-starttime));
                    i=2;
                }
                log.info("接收第一帧时间--》数据接收完准备合成");
                CompletableFuture<JSONObject> future = CompletableFuture.supplyAsync(() -> {
                    long start = System.currentTimeMillis();
                    byte[] bytes = HexUtil.decodeHex(imgHexStr);
                        byte[] arr = BayerGRUtil.writeBayerBmpFile(bytes, width, height);

                            //随机字符
                            String idStr = IdWorker.getIdStr();
                            //生成图片
                       //     long time4 = System.currentTimeMillis();
                            int png = LaptopConstant.nativeImageIO.write2BGRAndScale(arr, height, width, "/data/images/", idStr + ".png", "png", 0.9);
                  //          long time5 = System.currentTimeMillis();
//                            time4 = time5-time4;
//                            System.out.println("write2BGRAndScale合成图片时间 ===" + time4 );

                            String imageUrl = "http://" + imageurl + "/jeecg-boot/test/gmvVideo/getImage/" + idStr + ".png";
                            log.info("imageUrl = " + imageUrl);


                            content.put("imageUrl", imageUrl);
                            content.put("idsName", idsName);
                            //获取时间
                            //   String secondStr = content.getString(LaptopConstant.SECOND_FIELD_MAP.get(idsName)).split(";")[1];
                            //   String subSecondStr = content.getString(LaptopConstant.SUB_SECOND_FIELD_MAP.get(idsName)).split(";")[1];
                            String[] split = secondStr.split(":");
                            content.put("ts", split[0] + "天" + split[1] + "时" + split[2] + "分" + split[3] + "秒" + subSecondStr + "微秒");
                            content.remove(LaptopConstant.FRAME_FIELD_MAP.get(idsName));
                            //将图片添加到map


                    content.put("key", key);
                    log.info("两相柜6D1DH_40H,6D1EH_40H,6D21H_40H,6D22H_40H 合成图片消耗时间：" + (System.currentTimeMillis() - start) + "毫秒");
                    return content;
                },taskExecutePool.threadPoolTaskExecutor2());
                LaptopConstant.imageFutureList.add(future);

                    }


            //获取数据 并添加
            queue = new StringBuilder();
            queue.append(dataFrames);
            LaptopConstant.imageData.put(key, queue);
        }

        //存入图像编号到map
        LaptopConstant.imageNumMap.put(key, currImageNum);
        return true;
    }

    //TGMTYY1401_09CH_31_TPSRAPP1,TGMTYY1401_09CH_31_TPSRAPP2,TGMTYY1401_09CH_31_TPSRAPP5,TGMTYY1401_09CH_31_TPSRAPP6
    public static void main(String[] args) {
        System.load("D:/disk1/libjpeg-9.dll");
        System.load("D:/disk1/libpng-3.dll");
        System.load("D:/disk1/NativeImageIOJNI.dll");
        //"D:\\pc_workspace\\数据\\两相柜\\"+"40_6D1D_0.txt"   D:\图像数据\两相柜
        List<String> strings = FileUtil.readUtf8Lines("D:\\图像数据\\两相柜\\T20230322110745_0001_009c_F1_00_6DCD_2024_0040_40_6D1D_000000000.txt");
        LiangxiangguiApp1Service liangxiangguiApp1Service = new LiangxiangguiApp1Service();

        for (String string : strings) {
            //将str转化为相应的JSONObject对象
            JSONObject jsonObject = JSONObject.parseObject(string);
//TGMTYY1401_09CH_31_TPSRAPP1UDP               TGMTYY1401_09CH_31_TPSRAPP1  TGMTYY1401_09CH_31_TPSRAPPUDP1   6D20H_40H
            liangxiangguiApp1Service.merge(jsonObject, "6D1DH_40H", "6D1DH_40H");
        }

    }

    //UDP数据获取图像序号 长宽等信息
    public static JSONObject parse(String str, String idsName) {
        //55aa6d1d400012ac0390ac5f566403220390aaff4b2e0000022a040804080821
        JSONObject jsonObject = new JSONObject();
        //Map<String, String> map = new HashMap<>();
        String secondStr = str.substring(0, 8);
        String subSecondStr = str.substring(8, 12);
        String imageNoStr = str.substring(12, 20);
        String xStr = str.substring(20, 24);
        String yStr = str.substring(24, 28);
        String weishenStr = str.substring(28, 30);
        String taskNoStr = str.substring(30, 32);
        String dataStr = str.substring(32);

        Integer second = NumberUtil.versbyte2Integer(HexUtil.decodeHex(secondStr), 0);


        jsonObject.put("second", secondStr + "H;" + HeaderUtil.getShipSecond(second.longValue()) + ";时间戳秒;否");
        jsonObject.put("subsecond", subSecondStr + "H;" + NumberUtil.versbyte22Integer(HexUtil.decodeHex(subSecondStr), 0) * 40 + ";时间戳亚秒;否");
        jsonObject.put(LaptopConstant.IMAGENUM_FIELD_MAP.get(idsName), imageNoStr + "H;" + Integer.parseUnsignedInt(imageNoStr, 16) + ";图像序号;否");
        System.out.println("jsonObject.getString(LaptopConstant.IMAGENUM_FIELD_MAP.get(idsName)) = " + jsonObject.getString(LaptopConstant.IMAGENUM_FIELD_MAP.get(idsName)));
        Integer x = Integer.parseUnsignedInt(xStr, 16);
        if (x <= 10) {
            return null;
        }
        jsonObject.put(LaptopConstant.WIDTH_FIELD_MAP.get(idsName), x+";"+xStr + "H" + ";分辨率X;否");
        Integer y = Integer.parseUnsignedInt(yStr, 16);
        if (y <= 10) {
            return null;
        }
        jsonObject.put(LaptopConstant.HEIGHT_FIELD_MAP.get(idsName), y+";"+yStr + "H" + ";分辨率Y;否");
        jsonObject.put("A1_FPR_MICU_APP19DATA_24_24_1", weishenStr + "H;" + Integer.parseUnsignedInt(weishenStr, 16) + ";位深;否");
        jsonObject.put("A1_TPSR_MICU_APP1DATA_31_31_1", taskNoStr + "H;" + Integer.parseUnsignedInt(taskNoStr, 16) + ";任务号;否");
        jsonObject.put(LaptopConstant.FRAME_FIELD_MAP.get(idsName), "null;0x" + dataStr + ";null;null");


        return jsonObject;
    }
}
